package com.ytd.common.util;

import android.text.TextUtils;

import com.ytd.common.bean.BaseRequest;
import com.ytd.common.bean.HolidayInfo;
import com.ytd.common.bean.TimerInfo;
import com.ytd.common.bean.request.StartupConfigRequestData;
import com.ytd.common.bean.response.StartupConfigResponse;
import com.ytd.common.constant.ApiConstants;
import com.ytd.common.net.NetCallBack;
import com.ytd.common.net.RequestManager;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 定时器管理
 * 定时开关机处理任务
 *
 * @author gaoguanchao
 * @since 2023/11/2 0002
 */
public class TimerManager {

    public static final String TAG = "TimerManager";
    //先判断今天周几。

    //然后匹配最新的日期的开关机配置

    //判断是否是工作日模式

    //判断是否是工作日

    //设置最近的开机时间，关机时间

    //下次开机后继续匹配
    //开机时间列表
    private List<TimerInfo> timeOnList = new ArrayList();
    private List<TimerInfo> timeOffList = new ArrayList();
    private List<String> restDateList = new ArrayList();
    private List<String> workDateList = new ArrayList();
    private StartupConfigResponse response;
    private Date shutdownTime;
    private Date startupTime;

    private final static Map<Integer, String> constant_week = new HashMap<>();
    private final static List<Integer> def_work_day = new ArrayList<>();
    private final static List<Integer> def_holiday = new ArrayList<>();

    static {
        constant_week.put(Calendar.MONDAY, "1");
        constant_week.put(Calendar.TUESDAY, "2");
        constant_week.put(Calendar.WEDNESDAY, "3");
        constant_week.put(Calendar.THURSDAY, "4");
        constant_week.put(Calendar.FRIDAY, "5");
        constant_week.put(Calendar.SATURDAY, "6");
        constant_week.put(Calendar.SUNDAY, "7");

        def_work_day.add(Calendar.MONDAY);
        def_work_day.add(Calendar.TUESDAY);
        def_work_day.add(Calendar.WEDNESDAY);
        def_work_day.add(Calendar.THURSDAY);
        def_work_day.add(Calendar.FRIDAY);

        def_holiday.add(Calendar.SATURDAY);
        def_holiday.add(Calendar.SUNDAY);
    }


    public void initData() {
        BaseRequest request = new BaseRequest();
        request.interfaceName = ApiConstants.GET_STARTUP_SHUTDOWN_CONFIG_LIST;
        StartupConfigRequestData configRequest = new StartupConfigRequestData();
        configRequest.updateTime = FormatUtil.getDateFormat(new Date(0));
        request.data = configRequest;
        request.timeout = 3000;
        RequestManager.getInstance().request(request, new NetCallBack<StartupConfigResponse>() {
            @Override
            public void onSuccess(StartupConfigResponse result) {
                YtdConfig.setStartTime(0);
                response = result;
                restDateList.clear();
                workDateList.clear();
                for (HolidayInfo holiday : response.holidays) {
                    restDateList.addAll(holiday.vacations);
                    workDateList.addAll(holiday.makeUpWorkdays);
                }
                saveLocal();
            }

            @Override
            public void onFail(int code, String msg) {
                readLocal();
            }
        });
    }

    private synchronized void parseTimeList(StartupConfigResponse response, Calendar calendar) {
        int weekday = calendar.get(Calendar.DAY_OF_WEEK);
        //筛选今天
        String currentWeekDay = constant_week.get(weekday);
        Date time = calendar.getTime();
        String dateString = FormatUtil.getDayFormat2(time);
        LogUtil.d(TAG, "dateString:" + dateString);
        timeOnList.clear();
        timeOffList.clear();
        //请求失败则进行读取本地
        for (TimerInfo config : response.configs) {//0-开机，1-关机
            if (config.enabled == 0 || config.deleted == 1) {
                continue;
            }

            if (config.mode == 0) {//普通模式
                if (!config.dayOfWeeks.contains(currentWeekDay)) {
                    continue;
                }
            } else {//智能模式
                if (config.intelligenceValid != 0 && config.intelligenceValid != 3) {
                    // （智能模式时必填）智能生效方式：1-工作日生效，2-节假日生效，3-都生效
                    if (config.intelligenceValid == 1) {
                        //校验今天是否是工作日
                        if (def_work_day.contains(weekday)) {
                            if (restDateList.contains(dateString)) {
                                continue;
                            }
                        } else {
                            if (!workDateList.contains(dateString)) {//判断是不是补班
                                continue;
                            }
                        }
                    } else {//校验今天是否是节假日
                        if (def_holiday.contains(weekday)) {
                            if (workDateList.contains(dateString)) {
                                continue;
                            }
                        } else {
                            if (!restDateList.contains(dateString)) {
                                continue;
                            }
                        }
                    }
                }
            }
            if (config.type == 0) { //0-开机，1-关机
                timeOnList.add(config);
            } else {
                timeOffList.add(config);
            }
        }
        //时间排序
        Collections.sort(timeOnList, timeComparator);
        Collections.sort(timeOffList, timeComparator);
    }

    Comparator timeComparator = new Comparator<TimerInfo>() {
        @Override
        public int compare(TimerInfo o1, TimerInfo o2) {
            if (o1.time.equals(o2.time)) {
                return 0;
            }
            String[] split = o1.time.split(":");
            String[] split1 = o2.time.split(":");
            if (FormatUtil.parseInt(split[0]) > FormatUtil.parseInt(split1[0])) {
                return 1;
            } else if (FormatUtil.parseInt(split[0]) < FormatUtil.parseInt(split1[0])) {
                return -1;
            }
            if (FormatUtil.parseInt(split[1]) > FormatUtil.parseInt(split1[1])) {
                return 1;
            } else {
                return -1;
            }
        }
    };

    Comparator timeStringComparator = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            if (o1.equals(o2)) {
                return 0;
            }
            String[] split = o1.split(":");
            String[] split1 = o2.split(":");
            if (FormatUtil.parseInt(split[0]) > FormatUtil.parseInt(split1[0])) {
                return 1;
            } else if (FormatUtil.parseInt(split[0]) < FormatUtil.parseInt(split1[0])) {
                return -1;
            }
            if (FormatUtil.parseInt(split[1]) > FormatUtil.parseInt(split1[1])) {
                return 1;
            } else {
                return -1;
            }
        }
    };

    /**
     * 获取第一个开机时间
     */
    public Date getFirstStartupTime() {
        if (startupTime != null && startupTime.after(new Date())) {
            return startupTime;
        }
        checkResponse();
        if (response == null || response.configs == null || response.configs.size() == 0) {
            LogUtil.d(TAG, "getFirstStartupTime null configs.isEmpty");
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        parseTimeList(response, calendar);
        Date time = calendar.getTime();
        String mealTime = FormatUtil.getMealTime(time);
        LogUtil.d(TAG, "mealTime:" + mealTime);
        TimerInfo tmp = null;
        //过滤超过现在的
        ArrayList<TimerInfo> infos = new ArrayList<>(timeOnList);
        for (TimerInfo timerInfo : infos) {
            if (timeStringComparator.compare(mealTime, timerInfo.time) <= 0) {
                tmp = timerInfo;
                break;
            }
        }
        int countMax = 10;
        int count = 1;
        while (tmp == null) {
            LogUtil.d(TAG, "getNextDayList");
            getNextDayList(calendar);
            infos = new ArrayList<>(timeOnList);
            if (infos.size() > 0) {
                tmp = infos.get(0);
            }
            count++;
            if (count >= countMax) {
                break;
            }
        }
        if (tmp != null) {
            String[] split = tmp.time.split(":");
            calendar.set(Calendar.HOUR_OF_DAY, FormatUtil.parseInt(split[0]));
            calendar.set(Calendar.MINUTE, FormatUtil.parseInt(split[1]));
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            startupTime = calendar.getTime();
            LogUtil.d(TAG, "计算开机时间：" + FormatUtil.getDateFormat(startupTime));
            return startupTime;
        }
        return null;
    }

    private void getNextDayList(Calendar calendar) {
        //没有符合的，就day+1 取第一个
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        parseTimeList(response, calendar);
    }

    /**
     * 获取第一个关机时间
     */
    public Date getFirstShutdownTime() {
        if (shutdownTime != null && shutdownTime.after(new Date())) {
            return shutdownTime;
        }
        checkResponse();
        if (response == null || response.configs == null || response.configs.size() == 0) {
            LogUtil.d(TAG, "getFirstStartupTime null configs.isEmpty");
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        parseTimeList(response, calendar);
        Date time = calendar.getTime();
        String mealTime = FormatUtil.getMealTime(time);
        TimerInfo tmp = null;
        ArrayList<TimerInfo> infos = new ArrayList<>(timeOffList);
        for (TimerInfo timerInfo : infos) {
            if (timeStringComparator.compare(mealTime, timerInfo.time) == 0) {//关机后重启，会是时间一样
                tmp = timerInfo;
                break;
            }
            if (timeStringComparator.compare(mealTime, timerInfo.time) < 0) {//过滤超过现在的
                tmp = timerInfo;
                break;
            }
        }
        int countMax = 15;
        int count = 1;
        while (tmp == null) {
            getNextDayList(calendar);
            infos = new ArrayList<>(timeOffList);
            if (infos.size() > 0) {
                tmp = infos.get(0);
            }
            count++;
            if (count >= countMax) {
                break;
            }
        }
        if (tmp != null) {
            String[] split = tmp.time.split(":");
            calendar.set(Calendar.HOUR_OF_DAY, FormatUtil.parseInt(split[0]));
            calendar.set(Calendar.MINUTE, FormatUtil.parseInt(split[1]));
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            shutdownTime = calendar.getTime();
            LogUtil.d(TAG, "计算关机时间：" + FormatUtil.getDateFormat(shutdownTime));
            return shutdownTime;
        }
        return null;
    }

    public void onPush(ArrayList<TimerInfo> timerInfoArrayList) {
        reset();
        checkResponse();
        ArrayList<TimerInfo> infos = new ArrayList<>();
        for (TimerInfo timerInfo : timerInfoArrayList) {
            if (timerInfo.deleted == 1 || timerInfo.enabled == 0) {
                infos.add(timerInfo);
                continue;
            }
            if (response.configs.contains(timerInfo)) {
                int i = response.configs.indexOf(timerInfo);
                response.configs.remove(i);
                response.configs.add(i, timerInfo);
                LogUtil.d(TAG, "更新：" + timerInfo);
            } else {
                response.configs.add(timerInfo);
                LogUtil.d(TAG, "添加：" + timerInfo);
            }
        }
        for (TimerInfo info : infos) {
            response.configs.remove(info);
            LogUtil.d(TAG, "删除：" + info);
//            if (response.configs.contains(info)) {
//                int i = response.configs.indexOf(info);
//                response.configs.remove(i);
//            }
        }
        saveLocal();
    }

    private void reset() {
        YtdConfig.setStartTime(0);
        shutdownTime = new Date();
        startupTime = new Date();
    }

    private void saveLocal() {
        //saveResponse
        String toJson = GsonUtil.toJson(response);
        YtdConfig.setShutdownLocal(toJson);
    }

    private void readLocal() {
        String shutdownLocal = YtdConfig.getShutdownLocal();
        if (TextUtils.isEmpty(shutdownLocal)) {
            response = new StartupConfigResponse();
            response.configs = new ArrayList<>();
            response.holidays = new ArrayList<>();
            return;
        }
        response = GsonUtil.fromJson(shutdownLocal, StartupConfigResponse.class);
    }

    private void checkResponse() {
        if (response == null) {
            readLocal();
            ThreadUtil.executeMainDelayed(this::initData, 10000);
        }
    }


    private TimerManager() {
    }

    public static TimerManager getInstance() {
        return ManagerHolder.instance;
    }

    private static class ManagerHolder {
        private static final TimerManager instance = new TimerManager();
    }
}
